﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Web;
using FastPoster.Helpers;
using FastPoster.MainForms;

namespace FastPoster.MainClasses
{
    public class VBB
    {
        private CookieContainer     _cookies;
        private string              _url;
        public string               UserAgent { get; set; }
        public string               ExceptionString { get; set; }
        public string               ResponseUrl { get; set; }
        public int                  Index { get; set; }
        public string               Accept { get; set; }
        public string               StrRespond { get; set; }

        public EventHandler ProgressChanged { get; set; }

        public VBB(string url)
        {
            ServicePointManager.UseNagleAlgorithm = false;
            ServicePointManager.Expect100Continue = false;
            this._url = url;
            if (!this._url.EndsWith("/"))
            {
                this._url = this._url + "/";
            }
            this._cookies = new CookieContainer();
            this.UserAgent = "Mozilla/5.0 (Windows NT 6.1; rv:6.0.2) Gecko/20100101 Firefox/6.0.2";
            this.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
            this.ExceptionString = string.Empty;
        }

        public void ClearCookies()
        {
            this._cookies = new CookieContainer();
        }

        public bool CreateNewReply(string threadsUrl, string m)
        {
            HTMLForm formByAction = HTMLForm.GetFormByAction(threadsUrl, this.GET(threadsUrl), "newreply.php");
            if (formByAction != null)
            {
                formByAction.Inputs["message"] = m;
                formByAction.Inputs["parseurl"] = 0;
                formByAction.Inputs["wysiwyg"] = 0;
                formByAction.Inputs.Remove("preview");
                string postData = formByAction.ToPostData();
                this.OnProgressChanged(new ProgressChangedArgs(this.Index, "posting a reply..."));
                if (this.POST(this._url + "newreply.php?do=postreply&t=" + UrlEncode(formByAction.Inputs["t"].ToString()), postData) != string.Empty)
                {
                    return true;
                }
            }
            else
            {
                this.ExceptionString = "Could not load page";
            }
            return false;
        }

        public bool CreateNewThread(string boxLink, string s, string m)
        {
            try
            {
                var get = this.GET(boxLink);
                if (get == string.Empty)
                {
                    this.OnProgressChanged(new ProgressChangedArgs(this.Index, this.ExceptionString));
                    return false;
                }
                HTMLForm formByAction = HTMLForm.GetFormByAction(boxLink, get, "newthread.php");
                if (formByAction != null)
                {
                    formByAction.Inputs["subject"] = s;
                    formByAction.Inputs["message"] = m;
                    formByAction.Inputs["postpoll"] = "no";
                    formByAction.Inputs["parseurl"] = 0;
                    formByAction.Inputs["wysiwyg"] = 0;
                    formByAction.Inputs.Add("prefixid", 3);
                    formByAction.Inputs.Remove("preview");
                    string postData = formByAction.ToPostData();

                    GlobalVariables.Logger.Info("Post new thread to box " + boxLink + ": started");
                    this.OnProgressChanged(new ProgressChangedArgs(this.Index, "Đăng bài mới..."));

                    var str = this.POST(boxLink, postData);
                    StrRespond = str;

                    if (str != string.Empty)
                    {
                        if (str.ToLower().Contains("humanverify"))
                        {
                            return false;
                        }
                        else
                        {
                            if (str.ToUpper().Contains("DUPLICATE"))
                            {
                                this.ExceptionString = "This thread is duplicated with any thread that you posted previous";
                                return false;
                            }
                            if (!this.ResponseUrl.Contains("newthread.php") && !this.ResponseUrl.Contains("login.php"))
                            {
                                return true;
                            }
                            this.ExceptionString = "Nội dung không hợp lệ.";
                        }
                    }
                }
                else
                {
                    this.ExceptionString = "Không thể load trang đăng tin";
                    GlobalVariables.Logger.Info("Post new thread to box " + boxLink + ": failed - error: Cannot load new thread page");
                }
                return false;
            }
            catch (Exception ex)
            {
                if (ex.InnerException != null)
                {
                    GlobalVariables.Logger.Error("Post new thread to box " + boxLink + ": failed - error: " + ex.InnerException.Message);
                }
                else
                {
                    GlobalVariables.Logger.Error("Post new thread to box " + boxLink + ": failed - error: " + ex.Message);
                }
                return false;
            }
        }

        public bool ReCreateNewThread(string boxLink, string s, string m, string humanverify)
        {
            var get = this.GET(boxLink);
            if (get == string.Empty)
            {
                this.OnProgressChanged(new ProgressChangedArgs(this.Index, this.ExceptionString));
                return false;
            }
            HTMLForm formByAction = HTMLForm.GetFormByAction(boxLink, get, "newthread.php");
            if (formByAction != null)
            {
                formByAction.Inputs["humanverify[input]"] = humanverify;
                formByAction.Inputs["subject"] = s;
                formByAction.Inputs["message"] = m;
                formByAction.Inputs["postpoll"] = "no";
                formByAction.Inputs["parseurl"] = 0;
                formByAction.Inputs["wysiwyg"] = 0;
                formByAction.Inputs["taglist"] = string.Empty;
                //formByAction.Inputs["iconid"] = 1;
                formByAction.Inputs.Add("prefixid", 1);
                formByAction.Inputs.Remove("preview");
                string postData = formByAction.ToPostData();
                this.OnProgressChanged(new ProgressChangedArgs(this.Index, "Đăng bài viết mới..."));

                var str = this.POST(boxLink, postData);
                StrRespond = str;
                if (str != string.Empty)
                {
                    if (str.ToLower().Contains("humanverify"))
                    {
                        return false;
                    }
                    else
                    {
                        if (!this.ResponseUrl.Contains("newthread.php") && !this.ResponseUrl.Contains("login.php"))
                        {
                            return true;
                        }
                        if (str.ToUpper().Contains("CẢM ƠN") || str.ToUpper().Contains("CÁM ƠN"))
                        {
                            return true;
                        }
                        this.ExceptionString = "Nội dung không hợp lệ.";
                    }
                }
            }
            else
            {
                this.ExceptionString = "Không thể load trang đăng tin";
            }
            return false;
        }

        public string GET(string url)
        {
            string str = string.Empty;
            try
            {
                HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
                request.Accept = this.Accept;
                request.KeepAlive = true;
                request.Timeout = 0x7530;
                request.ReadWriteTimeout = 0x7530;
                request.Method = "GET";
                request.UserAgent = this.UserAgent;
                request.CookieContainer = this._cookies;
                request.Referer = url;
                
                GlobalVariables.Logger.Info("Get box link " + url + ": started");
                this.OnProgressChanged(new ProgressChangedArgs(this.Index, "Lấy link trang đăng tin..."));

                HttpWebResponse response = (HttpWebResponse) request.GetResponse();
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    GlobalVariables.Logger.Info("Get box link " + url + ": done");
                    using (Stream stream = response.GetResponseStream())
                    {
                        using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
                        {
                            str = reader.ReadToEnd();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (ex.InnerException != null)
                {
                    this.ExceptionString = "Get box link " + url + ": failed - error: " + ex.InnerException.Message;
                }
                else
                {
                    this.ExceptionString = "Get box link " + url + ": failed - error: " + ex.Message;
                }
                GlobalVariables.Logger.Error(this.ExceptionString);
            }
            return str;
        }

        public static string HtmlDecode(string url)
        {
            return HttpUtility.HtmlDecode(url);
        }

        public bool Login(string user, string pass)
        {
            this.OnProgressChanged(new ProgressChangedArgs(this.Index, "Đang đăng nhập..."));
            string postData = string.Format("vb_login_username={0}&vb_login_password={1}&securitytoken=guest&cookieuser=checked&do=login&vb_login_md5password=&vb_login_md5password_utf=", UrlEncode(user), UrlEncode(pass));
            string str2 = this.POST(this._url + "login.php", postData);
            if ((!str2.Contains("Thank you for logging in") && !str2.Contains("Redirecting")) && !str2.Contains(user))
            {
                return str2.Contains("Đang chuyển");
            }
            return true;
        }

        public bool IsBoxDied(string url)
        {
            var strReponse = this.GET(url);
            if (strReponse.ToLower().Contains("if you followed a valid link") || strReponse.ToLower().Contains("không có chủ đề") || url.Contains("newthread.php") || strReponse.ToLower().Contains("không tồn tại"))
            {
                return true;
            }
            return false;
        }

        protected void OnProgressChanged(ProgressChangedArgs e)
        {
            if (this.ProgressChanged != null)
            {
                this.ProgressChanged(this, e);
            }
        }

        public string POST(string url, string postData)
        {
            string str = string.Empty;
            HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
            request.Accept = this.Accept;
            request.KeepAlive = true;
            request.Timeout = 0x7530;
            request.ReadWriteTimeout = 0x7530;
            request.ContentType = "application/x-www-form-urlencoded";
            request.Method = "POST";
            request.UserAgent = this.UserAgent;
            request.CookieContainer = this._cookies;
            request.ContentLength = postData.Length;
            request.AllowAutoRedirect = true;
            request.Referer = this._url;

            try
            {
                this.OnProgressChanged(new ProgressChangedArgs(this.Index, "Submit form..."));
                System.Net.ServicePointManager.Expect100Continue = false; // prevents 417 error

                using (Stream stream = request.GetRequestStream())
                {
                    using (StreamWriter writer = new StreamWriter(stream, System.Text.Encoding.ASCII))
                    {
                        writer.Write(postData);
                    }
                }

                this.OnProgressChanged(new ProgressChangedArgs(this.Index, "Chờ phản hồi..."));

                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    // Get reponse stream
                    using (Stream stream2 = response.GetResponseStream())
                    {
                        using (StreamReader reader = new StreamReader(stream2, Encoding.UTF8))
                        {
                            str = HttpUtility.HtmlDecode(reader.ReadToEnd());
                        }         
                    }
                    this.ResponseUrl = response.ResponseUri.AbsoluteUri;
                }     
            }
            catch (Exception ex)
            {
                if (ex.InnerException != null)
                {
                    GlobalVariables.Logger.Error("Error on posting " + url + ": " + ex.InnerException.Message);
                }
                else
                {
                    GlobalVariables.Logger.Error("Error on posting " + url + ": " + ex.Message);
                }
                this.ExceptionString = ex.Message;
            }
            return str;
        }

        public static string UrlEncode(string text)
        {
            return HttpUtility.UrlEncode(text);
        }
    }
}
